package com.carol.bigdata.utils;
/*
 * @ClassName: IPUtil
 * @Description: TODO
 * @Author: carol
 * @Date: 2021/1/22 15:34
 * @Version: 1.0
 */

import org.javatuples.Triplet;
import org.lionsoul.ip2region.*;

import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Method;
import java.util.HashMap;

/*
 调用方法
 1. 下载ip2region.pb到本地 dbPath=pb文件绝对路径
 2. new IpUtil(dbPath）
 */
public class IpUtil {

    private String dbPath = "";
    private String algorithm = "btreeSearch";
    DbSearcher searcher = null;

    // 构造函数
    public IpUtil(String dbPath, String algorithm) throws DbMakerConfigException, FileNotFoundException {
        this.dbPath = dbPath;
        this.algorithm = algorithm; // "binarySearch" / "memorySearch"
        DbConfig config = new DbConfig();
        this.searcher = new DbSearcher(config, dbPath);
        System.out.println(String.format("IpUtil: dbPath: %s, algorithm: %s", dbPath, algorithm));
    }


    public IpUtil(String dbPath) throws DbMakerConfigException, FileNotFoundException {
        this.dbPath = dbPath;
        DbConfig config = new DbConfig();
        this.searcher = new DbSearcher(config, dbPath);
        System.out.println(String.format("IpUtil: dbPath: %s, algorithm: %s", dbPath, algorithm));
    }

    public IpUtil(HashMap<String, String> minioInfo) throws DbMakerConfigException, FileNotFoundException {
        File file = new File(dbPath);
        DbConfig config = new DbConfig();
        this.searcher = new DbSearcher(config, dbPath);
        System.out.println(String.format("IpUtil: dbPath: %s, algorithm: %s", dbPath, algorithm));
    }



    // 获取城市信息
    public HashMap<String, String> getCityInfo(String ip) {
        HashMap<String, String> res = new HashMap<String, String>();
        Triplet<String, String, String> triplet = parseIp(ip);
        System.out.println("triplet:" + triplet);
        res.put("code", triplet.getValue0());
        res.put("message", triplet.getValue1());
        // 中国|0|上海|上海市|联通
        String dataStr = triplet.getValue2();
        String[] split = dataStr.split("\\|");
        if (split.length == 5) {
            res.put("country", split[0]);
            res.put("province", (split[2].equals("0")) ? split[3] : split[2]);
            res.put("city", (split[3].equals("0")) ? split[2] : split[3]);
            res.put("network", split[4]);
        }
        return res;
    }


    // 解析IP,进行校验
    private Triplet<String, String, String> parseIp(String ip) {
        String code = "0";
        String message = "ok";
        String data = "";
        // 判断是否是ip地址
        if (!Util.isIpAddress(ip)) {
            code = "1000";
            message = "Error: Invalid ip address";
            return new Triplet<String, String, String>(code, message, data);
        }
        // 加载ip的db文件,判断是否存在
        // File file = new File(dbPath);
        // if (!file.exists()) {
        //     code = "1000";
        //     message = String.format("File is not exist: %s", dbPath);
        //     return new Triplet<String, String, String>(code, message, data);
        // }
        try {
            // 非线程安全,每次new实例
            // 查询算法 速度 m > bt > bi， bt,bi基于db文件,词盘模式
            // DbConfig config = new DbConfig();
            // DbSearcher searcher = new DbSearcher(config, dbPath);
            //define the method
            Method method = this.searcher.getClass().getMethod(algorithm, String.class);
            DataBlock dataBlock = (DataBlock) method.invoke(this.searcher, ip);
            data = dataBlock.getRegion();
            return new Triplet<String, String, String>(code, message, data);

        } catch (Exception e) {
            code = "1000";
            message = "查询算法出错";
            e.printStackTrace();
            return new Triplet<String, String, String>(code, message, data);
        }
    }


    // 测试用例
    public static void main(String[] args) throws Exception {
        com.carol.bigdata.utils.IpUtil ipUtils = new com.carol.bigdata.utils.IpUtil("/Users/carol/dev/huoys/utils/src/main/maker/ip2region.db");
        for (int i = 0; i < 1; i++) {
            String ip = "220.248.12.158";
            System.out.println(String.format("ip: %s, cityInfo: %s", ip, ipUtils.getCityInfo(ip)));
            ip = "47.244.254.50";
            System.out.println(String.format("ip: %s, cityInfo: %s", ip, ipUtils.getCityInfo(ip)));
            ip = "119.123.241.176";
            System.out.println(String.format("ip: %s, cityInfo: %s", ip, ipUtils.getCityInfo(ip)));
            ip = "1.1.127.255";  // 土耳其, CZ88.NET
            System.out.println(String.format("ip: %s, cityInfo: %s", ip, ipUtils.getCityInfo(ip)));
        }
    }

}
